﻿using System;
using System.Collections;
using System.Collections.Generic;
namespace TheSnakeGame.Engine.GameObjects
{
    /// <summary>
    /// Represent the Snake head
    /// </summary>
    public class SnakeHead : GameObject
    {
        private int snakeLength;
        private LinkedList<SnakeBodyPart> snakeBody;
        private Directions moveDirection;

        public SnakeHead(Point position, int length)
            : base(position)
        {
            if (length <= 0 || position.X < 0 || position.Y < 0)
            {
                throw new ArgumentOutOfRangeException("Length must be at least zero. Position.X and Position.Y must be positive numbers");
            }

            this.snakeLength = length;
            this.snakeBody = new LinkedList<SnakeBodyPart>();

            for (int i = length - 1; i >= 1; i--)
            {
                var snakePart = new SnakeBodyPart(position.X + i, position.Y);
                this.snakeBody.AddFirst(snakePart);
            }

            this.MoveDirection = Directions.Left;
        }

        public Directions MoveDirection
        {
            get { return this.moveDirection; }
            set
            {
                if ((int)this.moveDirection + (int)value != 0)
                {
                    this.moveDirection = value;
                }
            }
        }

        public int Length
        {
            get { return this.snakeBody.Count + 1; }
        }

        public IEnumerable<SnakeBodyPart> Body
        {
            get { return this.snakeBody; }
        }

        /// <summary>
        /// Chages the snake posistion in the set direction each time this method is called
        /// </summary>
        public override void DoAction()
        {
            base.DoAction();

            this.PlaceLastBodyPartAtHeadLocation();
            switch (this.MoveDirection)
            {
                case Directions.None:
                    break;
                case Directions.Left:
                    this.MoveLeft();
                    break;
                case Directions.Top:
                    this.MoveTop();
                    break;
                case Directions.Right:
                    this.MoveRight();
                    break;
                case Directions.Bottom:
                    this.MoveButtom();
                    break;
                default:
                    break;
            }
        }

        private void PlaceLastBodyPartAtHeadLocation()
        {
            if (this.snakeBody.Count > 0)
            {
                var last = this.snakeBody.Last;
                last.Value.Position.X = this.Position.X;
                last.Value.Position.Y = this.Position.Y;
                this.snakeBody.RemoveLast();
                this.snakeBody.AddFirst(last.Value);
            }
        }

        private void MoveButtom()
        {
            this.Position.Y--;
        }

        private void MoveRight()
        {
            this.Position.X++;
        }

        private void MoveTop()
        {
            this.Position.Y++;
        }

        private void MoveLeft()
        {
            this.Position.X--;
        }
    }
}
